/**
 * 取模
 * User: Zhikang.Peng
 * Date: 2018/04/11 15:30
 */
package math

import (
	"gitee.com/thghh/jvmgo/instructions/base"
	"gitee.com/thghh/jvmgo/rtda"
	"math"
)

//将栈顶两int型数值作取模运算并将结果压入栈顶
type IREM struct{ base.NoOperandsInstruction }

func (self *IREM) Execute(frame *rtda.Frame) {
	stack := frame.OperandStack()
	v2 := stack.PopInt()
	v1 := stack.PopInt()
	if v2 == 0 {
		panic("java.lang.ArithmeticException: / by zero.")
	}
	result := v1 % v2
	stack.PushInt(result)
}

//将栈顶两long型数值作取模运算并将结果压入栈顶
type LREM struct{ base.NoOperandsInstruction }

func (self *LREM) Execute(frame *rtda.Frame) {
	stack := frame.OperandStack()
	v2 := stack.PopLong()
	v1 := stack.PopLong()
	if v2 == 0 {
		panic("java.lang.ArithmeticException: / by zero.")
	}
	result := v1 % v2
	stack.PushLong(result)
}

//将栈顶两float型数值作取模运算并将结果压入栈顶
type FREM struct{ base.NoOperandsInstruction }

func (self *FREM) Execute(frame *rtda.Frame) {
	stack := frame.OperandStack()
	v2 := stack.PopFloat()
	v1 := stack.PopFloat()
	result := float32(math.Mod(float64(v1), float64(v2))) //TODO
	stack.PushFloat(result)
}

//将栈顶两double型数值作取模运算并将结果压入栈顶
type DREM struct{ base.NoOperandsInstruction }

func (self *DREM) Execute(frame *rtda.Frame) {
	stack := frame.OperandStack()
	v2 := stack.PopDouble()
	v1 := stack.PopDouble()
	result := math.Mod(v1, v2) //TODO
	stack.PushDouble(result)
}
